/**
@file PriceMyHouse.js
@brief Main program constants and script functions

Price My House for Nokia mobile platforms.

@author © 2011 Enrico Miglino / Tech Consulting (enrico.miglino@ovi.com)
@author "Evimin Fiyati Price My House" is protected by the copyright law
@author Distributed under the LGPL 3.0 license.
@date 2011

@par Licensing notes

"Price My House" is free software: you can redistribute it
and/or modify it under the terms of the Lesser GNU General Public License
as published by the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

"Price My House" is distributed in the hope that it
will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Lesser GNU General Public License for more details.

You should have received a copy of the Lesser GNU General Public License
along with "Price My House".
If not, see <http://www.gnu.org/licenses/>.

@section mainSciptDetails Application methods and constants
@section AppDataParameter The AppData parameters.
This is a group of preset values used to initialize the AppData class
managing the configuration files with the application descriptive
content: strings, descriptions etc.
Using this method the UI textual information can be updated from the central server.
The AppData class includes also a mechanism to manage the localization
of the application (currently in Turkish and English languages).
Due to the AppData starts from a main root definition initialization is really very simple.

@section programState The program state mechanism
The entire application is thought to be a state machine. This means that not only the objects
are driven by states depending by the events fired by the user (buttons, checkboxes, switches lists etc)
but also the behavior of the application in any moment can be focused in a \b state of the entire application.
This approach simplify the different application stages and grant that a certain state when changes can
release the components that will now be used by the application itself.

@par programState property
The value of programState changes depending by the point of the program
every action of the program is done or checked depending on the state of the program
In this way (formerly a structural state-machine) every progrma object is almost independent
and it can be created, istantiated and changed with animations independently by the
global application logic that follows the different states of the program.

@par setProgramState() function
\b 0 is the initial (startup) state of the program.
Everytime the function is called the corresponding state actions are done and
the state changes alterating the behavior of the application.

 -# When in state 0 the function is called only by the accept button to confirm
the disclaimer acceptance.
 -# When in state 1 the user is logged in, else the stae can't change. After login
the map is shown in background and the user should confirm the acceptance of
the pricing method adopted by the application. Confirming the info page the
state changes.
 -# When in state 2 the only action the user can do is to accept the pricing
method (info page). Accepting the full program is unclocked to usage.
 -# The program state 3 is a "transitional state" and is note used in the normal flow.
When state 2 is completed the program state became 3 as unused: the toolbar buttons
set their own states (4, 5, 6) with different behaviors depending by the actions
of the program.
 -# State 4 is set by the Map button
 -# State 5 is set by the price my house button
 -# State 6 is set by the info button

When the function is called in state 1 it means that a login
operation was requested by the user. The user/password are checked
on the remote server and is all is done the user is accepted and the
program go ahead to the next state. If the login control does not
validate, the state remain the same and the user is asked to
login again.

@note State remain 1 until the user has not subscribe the pricing
method briefly explained in the info page.

@section toolbar Toolbar buttons management
Toolbar is shown when the users login to the application
but the buttons have not effect while the program is
in the state 1. This means that is the firs time that
the princing method info page is shown. While the user
don't accept the conditions the page is shown on top of the
screen. When the program state is > 2 the info page can be shown
but it is not persistent and the accept button is not mandatory
to go to the next steps.
When the program features are in a complete unlocked state every button
set its own proper state.
*/

//! @var var appBackground
//! @brief Application background color
var appBackground = "#000000";
//! @var var appTopBanner
//! @brief Relative banner height
var appTopBanner = 0.15;

//! @var var appToolBar
//! @brief Relative toolbar height
var appToolBar = 0.12;
//! @var var waitDuration, animDuration, waitSplash, animSplash
//! @brief Timers durations (ms) for transactions and animations
var waitDuration = 3000;
//! @var var waitDuration, animDuration, waitSplash, animSplash
//! @brief Timers durations (ms) for transactions and animations
var animDuration = 500;
//! @var var waitDuration, animDuration, waitSplash, animSplash
//! @brief Timers durations (ms) for transactions and animations
var waitSplash = 3000;
//! @var var waitDuration, animDuration, waitSplash, animSplash
//! @brief Timers durations (ms) for transactions and animations
var animSplash = 2000;

//! @var var rootFile
//! @brief The global file
var rootFile = "global"
//! @var var defaultLang
//! @brief Default language
var defaultLang = "en";
//! @var var configFolder
//! @brief Configuration files folder
var configFolder = "/data/";
/** @var var jsonObject
    @brief The JSON object that stores the json application parameters

    This is the object used to store the small json structure with the
    configuration parameters.
*/
var jsonObject = "";
//! @var var jsonApplication
//! @brief The JSON object that stores the application parameters
var jsonApplication = "";
//! @var var jsonApplication
//! @brief The JSON object that stores the application combo data.
var jsonCombo = "";
//! @var var fileCity
//! @brief The JSON file with the Cities list
var fileCity = "";
//! @var var fileDistrict
//! @brief The JSON file with District list
var fileDistrict = "";
//! @var var fileNeightbour
//! @brief The JSON file with Neighbourhood list
var fileNeighbour = "";
//! @var var filApp
//! @brief The JSON file with the application strings
var fileApp = "";
//! @var var fileCombo
//! @brief The JSON file name with combo values (lists)
var fileCombo = "";


//! @var var programState
//! @brief The currenst state of the application
var programState = 0;

/**
    @fn setProgramState()
    @brief Manages the program states of the application

    Manages the different program states and changes content and behavior of the 'Left'
    Main bottom button. The right button always remain the Exit button but depending on the
    state of the program, exits at different levels.
*/
function setProgramState() {
    switch (programState) {
    case 0: // State 0: Introductory informations and login + New user creation
        programState = 1;   // Set next state
        // Activate the next state elements
        loginUser.formShown = !loginUser.formShown;
        btnAccept.operation = "";
        break;
    case 1: // State 1: Main program management (top toolbar functions)
        if (checkLogin()) {
            programState = 2;   // Set the next state
            disclaimer.opacity = 0;
            background.opacity = 0;
            loginUser.formHidden = !loginUser.formHidden;
            // Force to show the info page
            toolbar.state = "Show";
            toolbarButtonInfo();
        }
        break;
    case 2: // State 2: Toolbar functions unlocked, show the map by default.
        programState = 3;   // Set the next state
        btnAccept.operation = "";
        toolbar.state = "Show";
        toolbarButtonHome();
        break;
    case 3: // Transition state: next values are the program operational states
        break;
    case 4: // Working on map
        basebuttons.visible = true;
        navButtons.visible = false;
        btnAccept.operation = appItem._mainbtntxt5;
        break;
    case 5: // Working on price my house parameter settings
        btnAccept.operation = "";
        basebuttons.visible = false;
        navButtons.visible = true;
        break;
    case 6: // Working on info button
        basebuttons.visible = true;
        navButtons.visible = false;
        btnAccept.operation = appItem._mainbtntxt4;
        break;
    }

}

/**
    @fn checkLogin()
    @brief Validate the user login form.

    Check for user login data and if login is ok, go ahead
    else show an error message and ask for login again.
    If the login is confirmed the function destroy all the
    objects no more needed.

    @note Controlled by the event \e loginUser.onLoginClicked
*/
function checkLogin() {

    newuserok.destroyNewUserOk = "";
    splashappItem.destroySplash = "";

    return true;
}

/**
    @fn showNewUser()
    @brief Display the form for new user registration.

    @note Controlled by the event \e loginUser.onNewuserClicked
*/
function showNewUser() {
    createUser.state = "enterNewUser";
}

/**
    @fn confirmNewUser()
    @brief Confirm new user registration

    @note Controlled by the event \e createUser.onNewuserClicked
*/
function confirmNewUser() {
    createUser.state = "exitNewUser";
    newuserok.state = "enterNewUserConfirm";
}

/*
  closeNewUser()
  Close new user confirmation form

  Event: NewUserConfirm.onNewuserClicked
  */
function closeNewUser() {
    newuserok.state = "exitNewUserConfirm";
}

//! @fn toolbarButtonMap()
//! @brief Manage the toolbar map button depending on the program state
function toolbarButtonMap() {
    if (programState > 2){
        infopage.state = "Hide";
        viewmap.state = "Show";
        formsprofile.state = "Hide";
        programState = 4;
        setProgramState();
    }
}

//! @fn toolbarButtonMap()
//! @brief Manage the toolbar home button depending on the program state
function toolbarButtonHome() {
    if (programState > 2){
        infopage.state = "Hide";
        viewmap.state = "Hide";
        formsprofile.state = "Show";
        programState = 5;
        setProgramState();
    }
}

//! @fn toolbarButtonMap()
//! @brief Manage the toolbar info button depending on the program state
function toolbarButtonInfo() {
    if (programState <= 3) {
        btnAccept.operation = appItem._mainbtntxt2;
    }
    else {
        programState = 6;
        setProgramState();
    }
    toolbar.state = "Hide";
    formsprofile.state = "Hide";
    viewmap.state = "Hide";
    infopage.state = "Show";
}

//! @fn processJsonConfData()
//! @brief Head function to manage the json file data for the application
//! parameters
function processJsonConfData() {

    switch (dataParameters.fname) {
    case rootFile:      // Global configuration file (internal)
        processGlobalConf();
        // Update the file name
        dataParameters.fname = fileApp;
        dataParameters.language = defaultLang;
        dataParameters.updateJson();
        break;
    case fileApp:
        processApplication();
        // Update the file name
        dataParameters.fname = fileCombo;
        dataParameters.language = defaultLang;
        dataParameters.updateJson();
        break;
    case fileCombo:
        processCombo();
        dataParameters.updateProperties();
        break;
    }
}

/**
@fn processGlobalConf()
@brief process the global configuration file and update the json object

After decoding the global fiel (the main file with the information on ther other
parameters the function initialize the properties for all the further actions.

@note The order of the parameters in the array of the global file is fixes and is
as follows:
 -# Cities list file name
 -# Districts list file name
 -# Neighbours list file name
 -# Application text values
 -# Combo lists field values

 @todo add the versioning management
*/
function processGlobalConf() {

    jsonObject = eval('(' + dataParameters.datastream + ')');

    // Assign the json values to the respective properties
    fileCity = jsonObject.updated[0].name;
    fileDistrict = jsonObject.updated[1].name;
    fileNeighbour = jsonObject.updated[2].name;
    fileApp = jsonObject.updated[3].name;
    fileCombo = jsonObject.updated[4].name;

    /////// for debug purposes
    console.log("\n\n *** processGlobalConf()");
    console.log("Cities: "+ fileCity);
    console.log("Districts: "+ fileDistrict);
    console.log("Neighbouroughs: "+ fileNeighbour);
    console.log("Application parameters: "+ fileApp);
    console.log("Combo parameters: "+ fileCombo);
    console.log("\n *** END of json parameters \n");
    /////// for debug purposes
}

/**
@fn processApplication()
@brief process the application parameters

Json data are parsed and stored in a object used to dynamically
assign the values to the respective objects properties.
*/
function processApplication() {

    /////// for debug purposes
    console.log("\n\n *** processApplication()");
    /////// for debug purposes

    jsonApplication = eval('(' + dataParameters.datastream + ')');

    /////// for debug purposes
    for (var index in jsonApplication.list) {
        console.log(jsonApplication.list[index].v
                    + " -> "
                    + jsonApplication.list[index].p);
    }
    console.log("\n *** END of json parameters \n");
    /////// for debug purposes
}

/**
@fn processCombo()
@brief process the combo text parameters

Json data are parsed and stored in a object used to dynamically
assign the values to the respective objects properties.
*/
function processCombo() {

    jsonCombo = eval('(' + dataParameters.datastream + ')');

    /////// for debug purposes
    console.log("\n\n *** prcessCombo()");
    for (var index in jsonCombo.list) {
        console.log("["
                    + jsonCombo.list[index].desc
                    + "] Param Name = "
                    + jsonCombo.list[index].paramname);
        for (var index2 in jsonCombo.list[index].list) {
            console.log(jsonCombo.list[index].list[index2].p
                        + ": "
                        + jsonCombo.list[index].list[index2].v);
        }
    }
    console.log("\n *** END of json parameters \n");
    /////// for debug purposes
}

/**
@fn getComboField(var)
@brief Extract the desired 1st leve field name from the json combo object

This object is a multi-level set of lists and the getComboField method extract
the description name of a group of fields based on the parameter name in the group.

@param var The group parameter name to search
@return The content of the required group description or the function parameter
itself if it does not exist.
*/
function getComboField(fldName) {
    for (var index in jsonCombo.list) {

        console.log("getComboField(" + fldName + ") [" + index + "] jsonCombo.list[index].paramname")

        if ( jsonCombo.list[index].paramname == fldName )
            return jsonCombo.list[index].paramname;
    }
    return fldName;
}

/**
@fn getAppField(var)
@brief Extract the desired field from the application json object

If the requested field name is not found in the json object the function
returns the field name itself, else returns the corresponding field content.

@param var The field name to search
@return The content of the required field name or the function parameter
itself if it does not exist.
*/
function getAppField(fldName) {
    for (var index in jsonApplication.list) {

        console.log("getAppField(" + fldName + ") ["
                    + index + "] jsonApplication.list[index].v = "
                    + jsonApplication.list[index].v +
                    " ... p = " + jsonApplication.list[index].p);

        if ( jsonApplication.list[index].v == fldName )
            return jsonApplication.list[index].p;
    }
    return fldName;
}

/**
@fn setMainProperties()
@brief Assign the json object values to the main application global properties
*/
function setMainProperties() {
    // Disclaimer URL
    appItem._disclaimerURL = Jmain.getAppField("urltxt1");

    // Main bottom buttons
    appItem._mainbtntxt1 = Jmain.getAppField("menu2");
    appItem._mainbtntxt2 = Jmain.getAppField("menu3");
    appItem._mainbtntxt3 = Jmain.getAppField("menu5");
    appItem._mainbtntxt4 = Jmain.getAppField("menu1");
    appItem._mainbtntxt5 = Jmain.getAppField("menu6");
    appItem._mainbtntxt6 = Jmain.getAppField("menu4");
    // Info page
    appItem.info_txt1 = Jmain.getAppField("txt7tit");
    appItem.info_txt2 = Jmain.getAppField("txt7");
    // Toolbar buttons text
    appItem._toolbartxt1 = Jmain.getAppField("tabv2");
    appItem._toolbartxt2 = Jmain.getAppField("tabv1");
    appItem._toolbartxt3 = Jmain.getAppField("tabv3");
    // Login form
    appItem.login_intro = Jmain.getAppField("txt2");
    appItem.login_txt1 = Jmain.getAppField("txt5");
    appItem.login_txt2 = Jmain.getAppField("txt6");
    appItem.login_txt3 = Jmain.getAppField("btn2");
    appItem.login_txt4 = Jmain.getAppField("btn1");
    appItem.login_txt8 = Jmain.getAppField("msg2");
    // Create new user form
    appItem.login_txt5 = Jmain.getAppField("btn1");
    appItem.login_txt7 = Jmain.getAppField("txt3");
    appItem.login_txt6 = Jmain.getAppField("menu4");
}

/**
@fn setHouseProperties()
@brief Assign the json object values to the PriceMyHouse multi-form object

This method assigns only the fixed values for the forms. The forms values that
depends from runtine user choices are assigned dinamically.
List contents (from combo json file) are assigned when the list is called
and the object is destrojed when it is no more needed.
*/
// Main bottom buttons
function setHouseProperties() {
    formsprofile._sectionName = Jmain.getAppField("head2");
    formsprofile._summaryPageTit = Jmain.getAppField("txt49");
    formsprofile._centerNavBtn = Jmain.getAppField("txt49");
    formsprofile._closeNavBtn = Jmain.getAppField("menu5");
    formsprofile._closeNavBtn = Jmain.getAppField("menu5");
    formsprofile.p1_txt1 = Jmain.getAppField("txt11");
    formsprofile.p1_txt2 = Jmain.getAppField("txt12");
    formsprofile.p1_txt3 = Jmain.getAppField("txt13");
    formsprofile.p1_txt4 = Jmain.getAppField("txt14");
    formsprofile.p1_txt5  = Jmain.getAppField("txt15");
}
